package com.zwh.common.utils.file;

import com.zwh.common.spring.SpringContextUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author zwh
 * @Date 2019/6/22 12:40
 **/
public class UploadUtils {
    private static final Logger logger = LoggerFactory.getLogger(UploadUtils.class);

    /**
     * 表单字段常量
     */
    public static final String FORM_FIELDS = "form_fields";
    /**
     * 文件域常量
     */
    public static final String FILE_FIELDS = "file_fields";
    // 最大文件大小
    private long maxSize = 1000000L;

    // 定义允许上传的文件扩展名
    private Map<String, String> extMap = new HashMap();
    // 文件保存目录相对路径
    private String basePath = "upload";
    // 文件的目录名
    private String dirName = "images";
    // 上传临时路径
    private static final String TEMP_PATH = "/temp";
    private String tempPath;
    // 若不指定则文件名默认为 yyyyMMddHHmmss_xyz
    private String fileName;
    // 文件保存目录路径
    private String savePath;
    // 文件保存目录url
    private String saveUrl;
    // 文件最终的url包括文件名
    private String fileUrl;

    public UploadUtils() {
        this.tempPath = this.basePath + "/temp";
        this.extMap.put("images", "gif,jpg,jpeg,png,bmp");
        this.extMap.put("flashs", "swf,flv");
        this.extMap.put("medias", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
        this.extMap.put("files", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
    }

    /**
    * 单/多文件上传
    * @param request
    * @return infos info[0] 验证文件域返回错误信息 info[1] 上传文件错误信息 info[2] savePath info[3] saveUrl info[4] fileUrl
    */
    public String[] uploadFile(HttpServletRequest request) {
        String[] infos = new String[5];
        infos[0] = this.validateFields(request);
        Map<String, Object> fieldsMap = new HashMap();
        if (infos[0].equals("true")) {
            fieldsMap = this.initFields(request);
        }

        List<FileItem> fiList = (List)((Map)fieldsMap).get("file_fields");
        if (fiList != null) {
            FileItem item;
            for(Iterator var5 = fiList.iterator(); var5.hasNext(); infos[1] = this.saveFile(item)) {
                item = (FileItem)var5.next();
            }

            infos[2] = this.savePath;
            infos[3] = this.saveUrl;
            infos[4] = this.fileUrl;
        }

        return infos;
    }

    /**
     * 上传验证,并初始化文件目录
     * @param request
     * @return
     */
    private String validateFields(HttpServletRequest request) {
        String errorInfo = "true";
        // 获取内容类型
        String contentType = request.getContentType();
        int contentLength = request.getContentLength();
        // 文件保存目录路径
        this.savePath = request.getSession().getServletContext().getRealPath("/") + this.basePath + "/";
        // 文件保存目录URL
        this.saveUrl = request.getContextPath() + "/" + this.basePath + "/";
        File uploadDir = new File(this.savePath);
        if (contentType != null && contentType.startsWith("multipart")) {
            if (this.maxSize < (long)contentLength) {
                System.out.println("上传文件大小超出文件最大大小");
                errorInfo = "上传文件大小超出文件最大大小[" + this.maxSize + "]";
            } else if (!ServletFileUpload.isMultipartContent(request)) {
                errorInfo = "请选择文件";
            } else if (!uploadDir.isDirectory()) {
                errorInfo = "上传目录[" + this.savePath + "]不存在";
            } else if (!uploadDir.canWrite()) {
                errorInfo = "上传目录[" + this.savePath + "]没有写权限";
            } else if (!this.extMap.containsKey(this.dirName)) {
                errorInfo = "目录名不正确";
            } else {
                // 创建文件夹
                this.savePath = this.savePath + this.dirName + "/";
                this.saveUrl = this.saveUrl + this.dirName + "/";
                File saveDirFile = new File(this.savePath);
                if (!saveDirFile.exists()) {
                    saveDirFile.mkdirs();
                }

                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                String ymd = sdf.format(new Date());
                this.savePath = this.savePath + ymd + "/";
                this.saveUrl = this.saveUrl + ymd + "/";
                File dirFile = new File(this.savePath);
                if (!dirFile.exists()) {
                    dirFile.mkdirs();
                }

                this.tempPath = request.getSession().getServletContext().getRealPath("/") + this.tempPath + "/";
                File file = new File(this.tempPath);
                if (!file.exists()) {
                    file.mkdirs();
                }
            }
        } else {
            System.out.println("请求不包含multipart/form-data流");
            errorInfo = "请求不包含multipart/form-data流";
        }

        return errorInfo;
    }

    private Map<String, Object> initFields(HttpServletRequest request) {
        Map<String, Object> map = new HashMap();
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(10485760);
            factory.setRepository(new File(this.tempPath));
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            upload.setSizeMax(this.maxSize);
            List items = null;

            try {
                items = upload.parseRequest(request);
            } catch (FileUploadException var13) {
                var13.printStackTrace();
            }

            if (items != null && items.size() > 0) {
                Iterator<FileItem> iter = items.iterator();
                List<FileItem> list = new ArrayList();
                HashMap fields = new HashMap();

                while(iter.hasNext()) {
                    FileItem item = (FileItem)iter.next();
                    if (item.isFormField()) {
                        String name = item.getFieldName();
                        String value = item.getString();
                        fields.put(name, value);
                    } else {
                        list.add(item);
                    }
                }

                map.put("form_fields", fields);
                map.put("file_fields", list);
            }
        }

        return map;
    }

    private String saveFile(FileItem item) {
        String error = "true";
        String fileName = item.getName();
        String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        if (item.getSize() > this.maxSize) {
            error = "上传文件大小超过限制";
        } else if (!Arrays.asList(((String)this.extMap.get(this.dirName)).split(",")).contains(fileExt)) {
            error = "上传文件扩展名是不允许的扩展名。\n只允许" + (String)this.extMap.get(this.dirName) + "格式。";
        } else {
            String newFileName;
            if ("".equals(fileName.trim())) {
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                newFileName = df.format(new Date()) + "_" + (new Random()).nextInt(1000) + "." + fileExt;
            } else {
                newFileName = fileName + "." + fileExt;
            }

            this.fileUrl = this.saveUrl + newFileName;

            try {
                File uploadedFile = new File(this.savePath, newFileName);
                item.write(uploadedFile);
            } catch (IOException var7) {
                var7.printStackTrace();
                System.out.println("上传失败了！！！");
            } catch (Exception var8) {
                var8.printStackTrace();
            }
        }

        return error;
    }




    public String getSavePath() {
        return this.savePath;
    }

    public String getSaveUrl() {
        return this.saveUrl;
    }

    public long getMaxSize() {
        return this.maxSize;
    }

    public void setMaxSize(long maxSize) {
        this.maxSize = maxSize;
    }

    public Map<String, String> getExtMap() {
        return this.extMap;
    }

    public void setExtMap(Map<String, String> extMap) {
        this.extMap = extMap;
    }

    public String getBasePath() {
        return this.basePath;
    }

    public void setBasePath(String basePath) {
        this.basePath = basePath;
        this.tempPath = basePath + "/temp";
    }

    public String getDirName() {
        return this.dirName;
    }

    public void setDirName(String dirName) {
        this.dirName = dirName;
    }

    public String getTempPath() {
        return this.tempPath;
    }

    public void setTempPath(String tempPath) {
        this.tempPath = tempPath;
    }

    public String getFileUrl() {
        return this.fileUrl;
    }

    public String getFileName() {
        return this.fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }


}
